/**
 * Cursor AccessToken 获取工具
 * 基于 WorkOS Token 自动获取 AccessToken
 */

// ============ Base64URL 编码工具函数 ============
const Slo = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

function base64URLEncode(data) {
  const n = Slo
  let s = ""
  const r = data.byteLength % 3
  let o = 0

  for (; o < data.byteLength - r; o += 3) {
    const a = data[o + 0]
    const u = data[o + 1]
    const d = data[o + 2]

    s += n[a >>> 2]
    s += n[((a << 4) | (u >>> 4)) & 63]
    s += n[((u << 2) | (d >>> 6)) & 63]
    s += n[d & 63]
  }

  if (r === 1) {
    const a = data[o + 0]
    s += n[a >>> 2]
    s += n[(a << 4) & 63]
  } else if (r === 2) {
    const a = data[o + 0]
    const u = data[o + 1]
    s += n[a >>> 2]
    s += n[((a << 4) | (u >>> 4)) & 63]
    s += n[(u << 2) & 63]
  }

  return s
}

// SHA256 哈希函数
async function sha256(inputString) {
  if (!crypto.subtle) {
    throw new Error("'crypto.subtle' is not available")
  }

  const encoder = new TextEncoder()
  const encodedData = encoder.encode(inputString)
  const hashBuffer = await crypto.subtle.digest("SHA-256", encodedData)

  return hashBuffer
}

// ============ Cookie 操作函数 ============

/**
 * 从 Chrome Cookie 中读取 WorkOS Token
 * @returns {Promise<string|null>} WorkOS Token 或 null
 */
async function getWorkosTokenFromCookie() {
  try {
    // 使用 Chrome Cookie API 读取
    return new Promise((resolve, reject) => {
      chrome.cookies.get(
        {
          url: "https://cursor.com",
          name: "WorkosCursorSessionToken"
        },
        cookie => {
          if (chrome.runtime.lastError) {
            console.error("读取 Cookie 失败:", chrome.runtime.lastError)
            reject(chrome.runtime.lastError)
          } else if (cookie) {
            console.log("✅ 成功从 Cookie 读取到 WorkOS Token")
            resolve(cookie.value)
          } else {
            console.warn("⚠️ 未找到 WorkosCursorSessionToken Cookie")
            resolve(null)
          }
        }
      )
    })
  } catch (error) {
    console.error("❌ 获取 Cookie 失败:", error)
    throw error
  }
}

function setWorkosCookie(workosToken) {
  // 设置 Cookie，有效期 30 天
  const expires = new Date()
  expires.setDate(expires.getDate() + 30)

  document.cookie = `WorkosCursorSessionToken=${workosToken}; domain=.cursor.com; path=/; expires=${expires.toUTCString()}; SameSite=Lax; Secure`

  console.log("✅ WorkosCursorSessionToken Cookie 已设置")
}

// ============ 核心：获取 AccessToken ============
async function getAccessToken(workosToken) {
  try {
    // 1. 先设置 Cookie
    setWorkosCookie(workosToken)

    // 2. 生成参数
    const K = new Uint8Array(32)
    crypto.getRandomValues(K)

    const verifier = base64URLEncode(K)
    const challenge = base64URLEncode(new Uint8Array(await sha256(verifier)))
    const uuid = crypto.randomUUID()

    console.log("📝 生成的参数:")
    console.log("  UUID:", uuid)
    console.log("  Verifier:", verifier)
    console.log("  Challenge:", challenge)

    // 3. 第一步：触发授权登录
    console.log("🔄 Step 1: 触发授权登录...")

    const loginResponse = await fetch("https://cursor.com/api/auth/loginDeepCallbackControl", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "*/*",
        Origin: "https://cursor.com"
      },
      credentials: "include", // 自动携带 Cookie
      body: JSON.stringify({
        challenge: challenge,
        uuid: uuid
      })
    })

    if (!loginResponse.ok) {
      throw new Error(`授权登录失败: ${loginResponse.status} ${loginResponse.statusText}`)
    }

    console.log("✅ Step 1 完成，服务器已准备好 Token")

    // 4. 第二步：轮询获取 AccessToken
    console.log("🔄 Step 2: 开始轮询获取 AccessToken...")

    return await pollForAccessToken(uuid, verifier)
  } catch (error) {
    console.error("❌ 获取 AccessToken 失败:", error)
    throw error
  }
}

// 轮询获取 AccessToken
async function pollForAccessToken(uuid, verifier, maxAttempts = 30) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      console.log(`🔍 轮询尝试 ${attempt}/${maxAttempts}...`)

      const pollUrl = `https://api2.cursor.sh/auth/poll?uuid=${uuid}&verifier=${verifier}`

      const response = await fetch(pollUrl, {
        method: "GET",
        headers: {
          Accept: "*/*",
          Origin: "https://cursor.com"
        }
      })

      if (response.ok) {
        const data = await response.json()

        if (data && data.accessToken) {
          console.log("✅ AccessToken 获取成功!")
          return data
        }
      }

      // 等待 1 秒后继续
      await new Promise(resolve => setTimeout(resolve, 1000))
    } catch (error) {
      console.warn(`⚠️ 第 ${attempt} 次轮询出错:`, error)
      await new Promise(resolve => setTimeout(resolve, 1000))
    }
  }

  throw new Error("轮询超时：未能在 30 秒内获取到 AccessToken")
}
